#pragma once
#include <iostream>
#include <string>
#include <pthread.h>
namespace The_Thread{
    class LockGuard
    {
        public:
            LockGuard(pthread_mutex_t* mutex) 
            : _mutex(mutex)
            {
                pthread_mutex_lock(_mutex);
            }
            ~LockGuard()
            {
                pthread_mutex_unlock(_mutex);
            }
        private:
            pthread_mutex_t* _mutex;
    };
    class ThreadDate{
        public:
            ThreadDate(const std::string& name, pthread_mutex_t* td)
            : _name(name)
            , _td(td)
            {}
        public:
            const std::string& _name;
            pthread_mutex_t* _td;
    };
    class Thread{
        typedef void (*func_t)(ThreadDate* td);
        public:
           void Excute(){
                std::cout << _name << "  running" << std::endl;
                _isrunning = true;
                _func(_td);
                pthread_cancel(_tid);
            }
        public:
            Thread(const std::string& name, func_t func, ThreadDate* td)
            : _name(name)
            , _func(func)
            , _td(td)
            {
                std::cout << _name << "  Create" << std::endl;
            }
            static void* ThreadRoutine(void* args){
                Thread* self = static_cast<Thread*>(args);
                self->Excute();
                return nullptr;
            }
            bool Start(){
                int n = ::pthread_create(&_tid, nullptr, ThreadRoutine, (void*)this);
                std::cout << _name << "  Start" << std::endl;
                if(n != 0)
                    return false;
                return true;
            }
            void Status(){
                if(_isrunning)
                    std::cout << "running" << std::endl;
                else
                    std::cout << "sleep" << std::endl;
            }
            std::string Getname(){
                return _name;
            }
            void Stop(){
                if(_isrunning)
                {
                    ::pthread_cancel(_tid);
                    _isrunning = false;
                    std::cout << _name << "  Stop" << std::endl;
                }
            }
            void Join(){
                    ::pthread_join(_tid, nullptr);
                     std::cout << _name << "  Join" << std::endl;
            }
            ThreadDate* GetThreaDate()
            {
                return _td;
            }
            ~Thread(){
                // Join();
                std::cout << _name << "  Destory" << std::endl;
            }
            
        private:
            std::string _name;
            pthread_t _tid;
            bool _isrunning;
            func_t _func;
            ThreadDate* _td;
    };
}
